package com.mew.user.events.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.RandomUtil;
import com.mew.user.config.EventsLastingConfig;
import com.mew.common.dc.db.ProfileService;
import com.mew.common.dc.mapper.EventsMapper;
import com.mew.common.enm.GoldProcessType;
import com.mew.common.entity.events.Events;
import com.mew.common.entity.events.EventsDays;
import com.mew.common.exception.ResponseCode;
import com.mew.common.rest.events.DaysGetResponseMessage;
import com.mew.common.rest.events.DaysInfoResponseMessage;
import com.mew.common.rest.events.DaysRouletteResponseMessage;
import com.mew.common.util.DateUtils;
import com.mew.common.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@Slf4j
public class DaysService {

    @Autowired
    private EventsLastingConfig eventsLastingConfig;
    @Autowired
    private EventsMapper eventsMapper;
    @Autowired
    private ProfileService profileService;

    public DaysInfoResponseMessage daysInf(long userId){
        EventsDays days = eventsMapper.getDays(userId);
        if (days == null){
            Events events = new Events(userId);
            events.setDaysDate(DateUtils.getTodayDate());
            eventsMapper.insert(events);
            days = new EventsDays();
            days.setUserId(userId);
            days.setDaysDate(events.getDaysDate());
        }

        long daysDate = Optional.ofNullable(days.getDaysDate()).orElse(DateUtils.getTodayDate());
        int isSame = DateUtils.betweenByLong(daysDate, System.currentTimeMillis(), DateUnit.DAY, true);
        if (isSame != 0){
            Events events = new Events(userId);
            events.setDaysDate(DateUtils.getTodayDate());
            events.setDaysGetDate(0L);
            events.setDaysTimes(0);
            events.setDaysBGetDate(0L);
            events.setDaysBTimes(0);
            events.setDaysRouletteTimes(0); //清0
            eventsMapper.updateById(events);


            String award = eventsLastingConfig.getDaysAward();
            String awardB = eventsLastingConfig.getDaysAwardB();

            DaysInfoResponseMessage message = new DaysInfoResponseMessage();
            message.setDaysGold(getAward(award, 0));
            message.setRemainTime(0);
            message.setDaysGoldB(getAward(awardB, 0));
            message.setRemainTimeB(0);
            message.setTotalTimes(0);
            message.setRoMaxGold(getMaxRoNumber());
            return message;

        }

        DaysInfoResponseMessage message = new DaysInfoResponseMessage();
        doAward(days, message);
        doAwardB(days, message);
        message.setRoMaxGold(getMaxRoNumber());
        message.setTotalTimes(getTimesTotal(days));
        return message;
    }

    private void doAward(EventsDays days, DaysInfoResponseMessage responseMessage){
        String award = eventsLastingConfig.getDaysAward();
        if (NumberUtil.isLtOne(days.getDaysGetDate())) {
            responseMessage.setDaysGold(getAward(award, 0));
            responseMessage.setRemainTime(0);
            days.setDaysTimes(0);
            return;
        }
        String time = eventsLastingConfig.getDaysTime();
        responseMessage.setDaysGold(getAward(award, days.getDaysTimes()));
        responseMessage.setRemainTime(getRemainTime(days.getDaysGetDate(), time, days.getDaysTimes()));

    }
    private void doAwardB(EventsDays days, DaysInfoResponseMessage responseMessage){
        String award = eventsLastingConfig.getDaysAwardB();
        if (NumberUtil.isLtOne(days.getDaysBGetDate())) {
            responseMessage.setDaysGoldB(getAward(award, 0));
            responseMessage.setRemainTimeB(0);
            days.setDaysBTimes(0);
            return;
        }
        if (days.getDaysBPrivilege() > 0){
            responseMessage.setDaysGoldB(getAward(award, days.getDaysTimes()));
            responseMessage.setRemainTimeB(0);
            return;
        }
        String time = eventsLastingConfig.getDaysTimeB();
        responseMessage.setDaysGoldB(getAward(award, days.getDaysTimes()));
        responseMessage.setRemainTimeB(getRemainTime(days.getDaysGetDate(), time, days.getDaysTimes()));
    }

    private long getAward(String goldAward, int times){
       String[] arg = goldAward.split("-");
       int base = Integer.parseInt(arg[0]);
       int up = Integer.parseInt(arg[1]);
       return NumberUtil.getGoldNumberByWan(base + (up * times));
    }

    public int getRemainTime(long startTime, String time, int times){
        String[] arg = time.split("-");
        int base = Integer.parseInt(arg[0]);
        int up = Integer.parseInt(arg[1]);
        int count = base + (up * times);
        if (startTime == 0){
            return count;
        }
        return DateUtils.remainTime(startTime, count, DateUnit.SECOND);
    }

    private long getMaxRoNumber(){
        String[] arg = eventsLastingConfig.getDaysRouletteInfo().split(",");
        return NumberUtil.getGoldNumberByWan(Integer.parseInt(arg[arg.length -1]));
    }

    /** 1，表示小， 2表示大 */
    public DaysGetResponseMessage daysGet(long userId, int type){
        EventsDays days = eventsMapper.getDays(userId);
        int remainTime = remainTime(days, type);
        if (remainTime > 0){
            return DaysGetResponseMessage.builder().build().buildByResponseCode(ResponseCode.DaysNotGet);
        }

        long gold = getAwardByDaysType(days, type);
        GoldProcessType goldProcessType = 1 == type ? GoldProcessType.Days : GoldProcessType.DaysB;
        long goldNumber = profileService.doGold(userId, gold, goldProcessType).getGoldNumber();

        Events events = new Events(userId);
        if (type == 1){
            events.setDaysTimes(days.getDaysTimes() + 1);
            events.setDaysGetDate(System.currentTimeMillis());
            days.setDaysTimes(events.getDaysTimes());
            days.setDaysGetDate(events.getDaysGetDate());
        }else {
            events.setDaysBTimes(days.getDaysBTimes() + 1);
            events.setDaysBGetDate(System.currentTimeMillis());
            days.setDaysBTimes(events.getDaysBTimes());
            days.setDaysBGetDate(events.getDaysBGetDate());
            if (days.getDaysBPrivilege() > 0){
                events.setDaysBPrivilege(days.getDaysBPrivilege() - 1);
                days.setDaysBPrivilege(events.getDaysBPrivilege());
            }
        }
        eventsMapper.updateById(events);

        int rt = remainTime(days, type);
        long nowGold = getAwardByDaysType(days, type);
        int totalTimes = getTimesTotal(days);
        return DaysGetResponseMessage.builder()
                .totalTimes(totalTimes)
                .daysGold(nowGold)
                .remainTime(rt)
                .goldNumber(goldNumber)
                .build();
    }

    private int remainTime(EventsDays days, int type){
        if (type == 2 && days.getDaysBPrivilege() > 0){
            return 0;
        }
        long startTime = type == 1 ? days.getDaysGetDate() : days.getDaysBGetDate();
        if (startTime == 0){
            return 0;
        }

        String time = type == 1 ? eventsLastingConfig.getDaysTime() : eventsLastingConfig.getDaysTimeB();
        int times = type == 1 ? days.getDaysTimes() : days.getDaysBTimes();
        int rt = getRemainTime(startTime, time, times);
        return rt;
    }

    private long getAwardByDaysType(EventsDays days, int type){
        String award = type == 1 ? eventsLastingConfig.getDaysAward() : eventsLastingConfig.getDaysAwardB();
        int times = type == 1 ? days.getDaysTimes() : days.getDaysBTimes();
        return getAward(award, times);
    }


    public DaysRouletteResponseMessage daysRoulette(long userId){
        EventsDays days = eventsMapper.getDays(userId);
        int totalTimes = getTimesTotal(days);
        if (totalTimes < 5){
            return DaysRouletteResponseMessage.builder().build().buildByResponseCode(ResponseCode.DaysNotWheel);
        }

        String wheel = eventsLastingConfig.getDaysRouletteInfo();
        String[] ws = wheel.split(",");
        int r = RandomUtil.randomInt(ws.length);
        long gold = NumberUtil.getGoldNumberByWan(Integer.parseInt(ws[r]));

        long goldNumber = profileService.doGold(userId, gold, GoldProcessType.DaysR).getGoldNumber();

        //----
        Events events = new Events(userId);
        events.setDaysRouletteTimes(days.getDaysRouletteTimes() + 1);
        days.setDaysRouletteTimes(events.getDaysRouletteTimes());
        eventsMapper.updateById(events);

        return DaysRouletteResponseMessage.builder()
                .totalTimes(getTimesTotal(days))
                .roGold(gold)
                .roIndex(r)
                .goldNumber(goldNumber)
                .build();
    }

    private int getTimesTotal(EventsDays days){
        int roTot = eventsLastingConfig.getDaysRouletteTimes();
        int didTimes = days.getDaysRouletteTimes() * roTot;
        return  days.getDaysTimes() + days.getDaysBTimes() - didTimes;
    }




}
